home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / HyperCard Related / XCMDs & XFCNs / DrawPictInRect / DrawPictInRect.p < prev    next >
Encoding:
Text File  |  1991-03-29  |  6.1 KB  |  282 lines  |  [TEXT/MPS ]

  1. {$R-}
  2. {$S DrawPictInRect }
  3.  
  4.  
  5.     DrawPictInRect (TargetRect, TextLabel)
  6.  
  7.      This HyperCard XFCN creates a drawing with the bounds that are passed in
  8.     TargetRect and leaves it on the clipboard to be pasted by HyperCard.
  9.     
  10.     The drawing that results is a true PICT; that is, it is object-oriented
  11.     and if it were saved in a file or pasted into another application, the 
  12.     objects would become editable.  Of course, once HyperCard pastes the 
  13.     PICT, it will no longer be editable; HyperCard converts everything to
  14.     bitmaps when they are pasted.
  15.     
  16.     TargetRect will be the picture frame of the PICT.  Its size is limited
  17.     to 0 (top and left) and 16000 (bottom and right).
  18.  
  19.     If the XFCN is successful, then empty is returned, otherwise the return value
  20.     is an error message.
  21.     
  22.     The drawing that is created is very boring: just a rectangle with an
  23.     X drawn through it, and a string drawn somewhere within it.
  24.     
  25.     Use this XFCN as a template for others that make more useful drawings.
  26.         
  27. }
  28.  
  29. UNIT DummyUnit;
  30.  
  31. INTERFACE
  32.  
  33.     USES {* ToolIntf, PackIntf, *}
  34.             Menus, Events, TextEdit, HyperXCmd, 
  35.             MemTypes, OSIntf, Scrap, QuickDraw, SANE;
  36.  
  37.     PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  38.  
  39. IMPLEMENTATION
  40.  
  41.     PROCEDURE DrawPictInRect(paramPtr: XCmdPtr);
  42.     FORWARD;
  43.  
  44.     PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  45.     BEGIN
  46.         DrawPictInRect(paramPtr)
  47.     END { entrypoint } ;
  48.  
  49.  
  50.     PROCEDURE DrawPictInRect(paramPtr: XCmdPtr);
  51.     CONST
  52.     
  53.     MinParams =        2;
  54.     MaxParams =        2;
  55.  
  56.     TYPE
  57.  
  58.     ParamArray =        PACKED ARRAY [1..MaxParams] OF Str255;
  59.  
  60.     VAR
  61.     
  62.     ParamStrings:        ParamArray;
  63.  
  64.     TargetRectParam:    Rect;
  65.     TextLabelParam:        Str255;
  66.  
  67.     ThePict:            PicHandle;
  68.         
  69.         PROCEDURE ExitWithString(aString: Str255);
  70.         BEGIN
  71.             WITH paramPtr^ DO BEGIN
  72.                 returnValue := PasToZero(paramPtr, aString);
  73.                 EXIT(DrawPictInRect);
  74.             END;
  75.         END;
  76.             
  77.         PROCEDURE ExitWithError(aString: Str255);
  78.         BEGIN
  79.             ExitWithString(concat('•••••••• Error: ', aString, '.'));
  80.         END;
  81.                         
  82.         PROCEDURE LimitRectValue(VAR ARect: Rect);
  83.         BEGIN
  84.             IF (ARect.Left < 0) THEN ARect.Left := 0;
  85.             IF (ARect.Top < 0) THEN ARect.Top := 0;
  86.             IF (ARect.Right > 16000) THEN ARect.Right := 16000;
  87.             IF (ARect.Bottom > 16000) THEN ARect.Bottom := 16000;
  88.         END;
  89.  
  90.         { 
  91.             This is where the drawing is done.  
  92.             DrawRect is the boundary of the drawing.
  93.             
  94.             Drawing is done in whatever Quickdraw context is current -- that is,
  95.             the code in this routine should be insensitive to whether drawing
  96.             is happening inside a bitmap or inside a PICT.
  97.             
  98.             For this sample XFCN, a border is drawn around/within the given rect,
  99.             an X is drawn across the rect, and the string specified by 
  100.             TextLabelParam is drawn somewhere in the middle.
  101.           
  102.          }
  103.         FUNCTION DoTheDrawing(DrawRect: Rect): BOOLEAN;
  104.         VAR            
  105.         
  106.             PenWidth:            Integer;
  107.             PenHeight:            Integer;
  108.             
  109.             Top:                LONGINT;
  110.             Left:                LONGINT;
  111.             Bottom:                LONGINT;
  112.             Right:                LONGINT;
  113.  
  114.         BEGIN
  115.         
  116.             PenWidth := 2;
  117.             PenHeight := 2;
  118.             
  119.             Left := DrawRect.Left;
  120.             Top := DrawRect.Top;
  121.             Right := DrawRect.Right;
  122.             Bottom := DrawRect.Bottom;
  123.             
  124.             { Make some calculations -- adjusting these for the pen size}
  125.             Right := Right - PenWidth;
  126.             Bottom := Bottom - PenWidth;
  127.             
  128.             { Start drawing }
  129.             PenSize(PenWidth,PenHeight);
  130.             MoveTo(Left,Top);
  131.             LineTo(Left,Bottom);            
  132.             LineTo(Right,Bottom);            
  133.             LineTo(Right,Top);            
  134.             LineTo(Left,Top);
  135.  
  136.             MoveTo(Left,Top);
  137.             LineTo(Right,Bottom);            
  138.  
  139.             MoveTo(Right,Top);
  140.             LineTo(Left,Bottom);            
  141.  
  142.             MoveTo(Left + 30, Top + 20);    
  143.             DrawString(TextLabelParam);
  144.  
  145.             DoTheDrawing := TRUE;
  146.  
  147.         END;
  148.         
  149.         FUNCTION GeneratePict: PicHandle;
  150.         VAR
  151.             OldGrafPtr:        GrafPtr;
  152.  
  153.             aGrafPort:        GrafPort;
  154.             aGrafPtr:        GrafPtr;
  155.  
  156.             ThePict:        PicHandle;
  157.             Success:        Boolean;
  158.         BEGIN
  159.         
  160.             { Remember the old GrafPort }
  161.             GetPort(OldGrafPtr);
  162.             
  163.             { Set up a new GrafPort }
  164.             aGrafPtr := @aGrafPort;
  165.             
  166.             OpenPort(aGrafPtr);
  167.         
  168.             aGrafPort.portRect := TargetRectParam;
  169.             RectRgn(aGrafPort.visRgn, TargetRectParam);
  170.             RectRgn(aGrafPort.clipRgn, TargetRectParam);
  171.  
  172.             { Open the Pict }
  173.             ThePict := OpenPicture(TargetRectParam);
  174.             
  175.             { Do the drawing }
  176.             Success := DoTheDrawing(TargetRectParam);
  177.  
  178.             { Close and return }
  179.             ClosePicture;
  180.             
  181.             { Restore the original GrafPort }
  182.             SetPort(OldGrafPtr);
  183.             
  184.             { Free the GrafPort we’ve been using}
  185.             ClosePort(aGrafPtr);
  186.  
  187.             IF (NOT Success) 
  188.             THEN 
  189.                 BEGIN
  190.                     KillPicture(ThePict);
  191.                     GeneratePict := NIL;
  192.                 END
  193.             ELSE GeneratePict := ThePict;
  194.         END;
  195.             
  196.         PROCEDURE DisposePict(ThePict: PicHandle);
  197.         BEGIN
  198.             KillPicture(ThePict);
  199.         END;
  200.             
  201.         FUNCTION PutPictOntoClipboard(ThePict: PicHandle): OsErr;
  202.         VAR
  203.             ErrValue:        LONGINT;
  204.         BEGIN
  205.  
  206.             ErrValue := ZeroScrap;
  207.             PutPictOntoClipboard := ErrValue;
  208.             IF (ErrValue <> NoErr)
  209.             THEN Exit(PutPictOntoClipboard);
  210.             
  211.             HLock(Handle(ThePict));
  212.             ErrValue := PutScrap(GetHandleSize(Handle(ThePict)),'PICT', Ptr(ThePict^));
  213.             HUnlock(Handle(ThePict));
  214.             
  215.             PutPictOntoClipboard := ErrValue;
  216.             IF (ErrValue <> NoErr)
  217.             THEN Exit(PutPictOntoClipboard);
  218.             
  219.         END;
  220.  
  221.         PROCEDURE CleanUpBeforeEnding;
  222.         BEGIN
  223.             DisposePict(ThePict);
  224.         END;
  225.             
  226.         PROCEDURE FailWithError(aString: Str255);
  227.         BEGIN
  228.  
  229.             CleanUpBeforeEnding;
  230.             ExitWithError(aString);
  231.         END;
  232.  
  233.         PROCEDURE ParseParams;
  234.         VAR
  235.             ParamNum:            integer;
  236.         BEGIN
  237.             WITH paramPtr^ DO 
  238.             BEGIN
  239.                 IF (paramCount < MinParams) THEN ExitWithError('Too few parameters');
  240.                 IF (paramCount > MaxParams) THEN ExitWithError('Too many parameters');
  241.             
  242.                 ParamNum := 1; {* Required *}
  243.                 
  244.                 ZeroToPas(ParamPtr, Params[ParamNum]^, ParamStrings[ParamNum]);
  245.                 StrToRect(paramPtr, ParamStrings[ParamNum], TargetRectParam);
  246.                 LimitRectValue(TargetRectParam);
  247.                 
  248.                 ParamNum := 2; {* Required *}
  249.                 
  250.                 ZeroToPas(paramPtr, Params[ParamNum]^, ParamStrings[ParamNum]);
  251.                 TextLabelParam := ParamStrings[ParamNum];                
  252.  
  253.             END;
  254.         END;
  255.             
  256.     BEGIN {DrawPictInRect}
  257.  
  258.         WITH paramPtr^ DO
  259.         BEGIN
  260.  
  261.             ParseParams;
  262.  
  263.             ThePict := GeneratePict;
  264.             IF (ThePict = NIL) THEN 
  265.             ExitWithError('Failed while generating picture');
  266.             
  267.             IF (PutPictOntoClipboard(ThePict) <> NoErr)
  268.             THEN FailWithError('Couldn’t place PICT on clipboard');
  269.             
  270.             CleanUpBeforeEnding; { i.e. dispose of the PICT before quitting }
  271.  
  272.             ExitWithString('');
  273.             
  274.         END
  275.  
  276.     END { DrawPictInRect } ;
  277.  
  278. END. { DummyUnit }
  279.  
  280.  
  281.